﻿using Studio77.FruitLinkLink.Entity;
using Studio77.FruitLinkLink.Pages;
using Studio77.FruitLinkLink.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;

namespace Studio77.FruitLinkLink.Views
{
    public class LinkGameCanvas : Canvas
    {
        private int[,] gameData;
        private Dictionary<int, LinkCard> linkCards = new Dictionary<int, LinkCard>();
        private Random r = new Random(DateTime.Now.Millisecond);
        private LinkCard selectCard = null;
        private int rowCount, columnCount, cardCount, currentClearCount;
        private Polyline linkLine = new Polyline();
        private ComboBlock combo = new ComboBlock();
        private double perWidth, perHeight;

        /// <summary>
        /// 连连看项变化范围
        /// </summary>
        private int itemChangeBase = 10;

        public LinkGameCanvas()
        {

        }

        public void StartNewGame(int type, int stage)
        {
            int row = 0, column = 0;
            switch (type)
            {
                case 1:
                    row = 6;
                    column = 9;
                    if (stage < 5)
                    {
                        itemChangeBase = 5;
                    }
                    else if (stage < 15)
                    {
                        itemChangeBase = 7;
                    }
                    else
                    {
                        itemChangeBase = 9;
                    }
                    break;
                case 2:
                    row = 8;
                    column = 12;
                    if (stage < 5)
                    {
                        itemChangeBase = 7;
                    }
                    else if (stage < 15)
                    {
                        itemChangeBase = 9;
                    }
                    else
                    {
                        itemChangeBase = 12;
                    }
                    break;
                case 3:
                    row = 10;
                    column = 15;
                    if (stage < 5)
                    {
                        itemChangeBase = 10;
                    }
                    else if (stage < 15)
                    {
                        itemChangeBase = 12;
                    }
                    else
                    {
                        itemChangeBase = 15;
                    }
                    break;
            }

            rowCount = row;
            columnCount = column;
            cardCount = row * column;
            currentClearCount = 0;

            //初始化游戏数据
            gameData = new int[row + 2, column + 2];
            RamdomGameData();
            linkLine.StrokeThickness = 3;
            linkLine.Stroke = new SolidColorBrush(Color.FromArgb(255, 220, 0, 0));

            RefreshCards();

        }

        private void RefreshCards()
        {
            //初始化界面
            linkCards.Clear();
            this.Children.Clear();
            perWidth = this.Width / columnCount;
            perHeight = this.Height / rowCount;
            //do layout
            for (int i = 1; i <= rowCount; i++)
            {
                for (int j = 1; j <= columnCount; j++)
                {
                    if (gameData[i, j] >= 0)
                    {
                        LinkCard card = new LinkCard();
                        Canvas.SetTop(card, (i - 1) * perWidth);
                        Canvas.SetLeft(card, (j - 1) * perHeight);
                        card.Width = perWidth;
                        card.Height = perHeight;
                        card.X = i;
                        card.Y = j;
                        card.SetValue(gameData[i, j]);
                        card.Tapped += card_Tapped;
                        Children.Add(card);
                        linkCards.Add(i * columnCount + j, card);
                    }
                }
            }

            combo.Height = perHeight / 2;
            combo.Width = combo.Height * 4;
        }

        void card_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
        {
            //click game cards
            LinkCard card = (LinkCard)sender;
            if (selectCard == null)
            {
                //No Selected Card
                card.SetSelectedCard();
                selectCard = card;
                AudioPlayHelper.PlayEffectSound("click.mp3");
            }
            else if (card != selectCard)
            {
                //Selected one card, should judgment two card
                //1.two card with same content
                if (card.Value == selectCard.Value)
                {
                    //2.can lined
                    if (LLKLogicHelper.CanEliminate(gameData, card.X, card.Y, selectCard.X, selectCard.Y, rowCount, columnCount))
                    {
                        gameData[card.X, card.Y] = -1;
                        gameData[selectCard.X, selectCard.Y] = -1;
                        //连线操作
                        SetLinkLine(card.X, card.Y, selectCard.X, selectCard.Y);
                        card.SetSelectedCard();

                        //show combo
                        if (GamePage.Instance.comboCount >= 2)
                        {
                            combo.setCombo(GamePage.Instance.comboCount);
                            Canvas.SetTop(combo, (card.X - 0.5) * perWidth);
                            Canvas.SetLeft(combo, (card.Y - 0.5) * perHeight);
                            if (!this.Children.Contains(combo))
                            {
                                this.Children.Add(combo);
                            }

                        }

                        DispatcherTimer timer = new DispatcherTimer();
                        timer.Interval = TimeSpan.FromMilliseconds(200);
                        timer.Tick += (object sendere, object ee) =>
                        {
                            this.Children.Remove(linkLine);
                            this.Children.Remove(card);
                            this.Children.Remove(selectCard);
                            this.Children.Remove(combo);
                            selectCard = null;
                            timer.Stop();
                        };
                        timer.Start();

                        currentClearCount += 2;
                        GamePage.Instance.Combo();
                        if (currentClearCount >= cardCount)
                        {
                            GamePage.Instance.Win();
                        }
                        AudioPlayHelper.PlayEffectSound("yes.mp3");

                        //Task task = new Task(() =>
                        //{
                        //    Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () =>
                        //    {
                        //        this.Children.Remove(linkLine);
                        //        this.Children.Remove(card);
                        //        this.Children.Remove(selectCard);
                        //        selectCard = null;
                        //    });
                        //});
                        //task.Start();

                    }
                    else
                    {
                        selectCard.SetUnSelectedCard();
                        selectCard = card;
                        card.SetSelectedCard();
                        AudioPlayHelper.PlayEffectSound("click.mp3");
                    }
                }
                else
                {
                    selectCard.SetUnSelectedCard();
                    selectCard = card;
                    card.SetSelectedCard();
                    AudioPlayHelper.PlayEffectSound("click.mp3");
                }
            }
        }

        private void SetLinkLine(int x1, int y1, int x2, int y2)
        {
            linkLine.Points.Clear();

            if (LLKLogicHelper.Type == 1)
            {
                //直线
                linkLine.Points.Add(GetPoint(x1, y1));
                linkLine.Points.Add(GetPoint(x2, y2));
            }
            else if (LLKLogicHelper.Type == 2)
            {
                //one conor
                linkLine.Points.Add(GetPoint(x1, y1));
                linkLine.Points.Add(GetPoint(LLKLogicHelper.lineX1, LLKLogicHelper.lineY1));
                linkLine.Points.Add(GetPoint(x2, y2));
            }
            else if (LLKLogicHelper.Type == 3)
            {
                //two conor
                linkLine.Points.Add(GetPoint(x1, y1));
                linkLine.Points.Add(GetPoint(LLKLogicHelper.lineX1, LLKLogicHelper.lineY1));
                linkLine.Points.Add(GetPoint(LLKLogicHelper.lineX2, LLKLogicHelper.lineY2));
                linkLine.Points.Add(GetPoint(x2, y2));
            }

            this.Children.Add(linkLine);
        }


        private Point GetPoint(int x1, int y1)
        {
            Point p = new Point();
            p.X = ((y1 - 1) * perHeight) + perHeight / 2.0;
            p.Y = ((x1 - 1) * perWidth) + perWidth / 2.0;

            return p;
        }

        /// <summary>
        /// 模拟游戏数据
        /// </summary>
        private void RamdomGameData()
        {
            //数据需要大一圈
            gameData = new int[rowCount + 2, columnCount + 2];
            int sum = rowCount * columnCount;

            for (int i = 0; i < rowCount + 2; i++)
            {
                for (int j = 0; j < columnCount + 2; j++)
                {
                    //清空数据
                    gameData[i, j] = -1;
                }
            }

            int temp = 0;
            for (int index = 0; index < sum / 2; index++)
            {
                temp = temp % itemChangeBase;
                
                for (int i = 0; i < 2; i++)
                {
                    int randomI = r.Next(1, rowCount + 1);
                    int randomJ = r.Next(1, columnCount + 1);
                    while (gameData[randomI, randomJ] != -1)
                    {
                        randomI = r.Next(1, rowCount + 1);
                        randomJ = r.Next(1, columnCount + 1);
                    }
                    gameData[randomI, randomJ] = temp + 1;
                }
                temp++;
            }
        }

        public void ReArrange()
        {
            // 重新洗牌，并修改LLKBlock对象中的Location
            // 找到所有没有被消除的块
            List<int> iList = new List<int>();
            List<int> jList = new List<int>();
            for (int i = 1; i < rowCount + 1; i++)
            {
                for (int j = 1; j < columnCount + 1; j++)
                {
                    if (gameData[i, j] >= 0)
                    {
                        iList.Add(i);
                        jList.Add(j);
                    }
                }
            }

            // 随机进行互换
            int halfCount = iList.Count / 2;
            for (int k = 0; k < halfCount; k++)
            {
                int i1 = iList[k];
                int j1 = jList[k];
                int randomK = halfCount + r.Next(halfCount);
                int i2 = iList[randomK];
                int j2 = jList[randomK];

                // 进行互换
                int temp = gameData[i1, j1];
                gameData[i1, j1] = gameData[i2, j2];
                gameData[i2, j2] = temp;
            }

            RefreshCards();
        }

        /// <summary>
        /// 使用提示道具
        /// </summary>
        public void UseFind()
        {
            var info = FindCouple();
            if (info != null)
            {
                //找到了
                LinkCard c1 = linkCards[info.X1 * columnCount + info.Y1];
                LinkCard c2 = linkCards[info.X2 * columnCount + info.Y2];
                c1.SetFind();
                c2.SetFind();
            }
        }

        /// <summary>
        /// 找到可以连接的一对
        /// </summary>
        /// <returns>如果没有找到 返回null</returns>
        private FindCardInfo FindCouple()
        {
            for (int i1 = 1; i1 <= rowCount + 1; i1++)
            {
                for (int j1 = 1; j1 <= columnCount + 1; j1++)
                {
                    if (gameData[i1, j1] >= 0)
                    {
                        //开始找，只是向后寻找
                        for (int i2 = i1; i2 <= rowCount + 1; i2++)
                        {
                            for (int j2 = 1; j2 <= columnCount + 1; j2++)
                            {
                                if (i1 != i2 && j1 != j2)
                                {
                                    if (gameData[i1, j1] == gameData[i2, j2])
                                    {
                                        //尝试连接下
                                        if (LLKLogicHelper.CanEliminate(gameData, i1, j1, i2, j2, rowCount, columnCount))
                                        {
                                            //找到了，返回
                                            FindCardInfo result = new FindCardInfo();
                                            result.X1 = i1;
                                            result.Y1 = j1;
                                            result.X2 = i2;
                                            result.Y2 = j2;
                                            return result;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }


            return null;
        }


    }
}
